package IceAssembly;

/**
 * The Check module contains functions that will be called
 * several times throughout the program's exection.  All functions act as a syntax or case 
 * checker that will return a 1 or 0 depending on the outcome. <p>
 * <p>
<b>Original Author:</b> Keith Hill
<p>
 */
public class Check {
    
    /**
    * The function isValidLabel will check to see if the label is syntactially correct.  It will begin 
    * by first checking to see if it is not an existing label and a valid mnemonic or Pseudo Op.  If 
     * it is an existing label, it will return 2.  If it is not an existing label, it
    *  will proceed by checking the content in the string.  
    * It will do this by checking the first character in the label.  If the label begins with 
    * anything other than a letter, it is not valid.  Then, it checks every character following and makes 
    * sure it is either a letter or number.  
    * <p>
    * Change Log:<br>
    * 4/14/08 - Initial code entry Keith Hill <br>
    * 4/16/08 - Finish character check Keith Hill<br>
    * 4/18/08 - Inserted pseud op, existing label, and mnemonic check Keith Hill<br>
    * 4/19/08 - Added the functionality of returning the value of 2 Keith Hill<br>
    * <p>
    * Error Conditions Tested:<br>
    * None <br>
    * <p>
    * Error Messages Generated: <br>
    * None <br>
    * <p>
    * Date of module being installed: 4/18/08
     * <p>
<b>Original Author:</b> Keith Hill
<p>
    * @param label this parameter is checked to see if it is a valid label
    * @return we return 1 if it is valid and not already in the symbol table, 
    * 0 if it is not syntactically correct, and 2 if it is already in the table.
     * */    
    public int isValidLabel (String label) {
      
        int length = label.length();
        String temp = label.toUpperCase();
        int result = isPseudoOP(temp);
        if (result == 1){
            return 0;
        }
        result = isMnemonic(temp);
        if(result == 1){
            return 0;
        }
        if(length == 0 || length >63){
            return 0;
        }
        int count = 0;
        
        while(count < 50){
            if(label.equals(Table.symbol_table[count][0]) && !Table.symbol_table[count][2].contentEquals("SHVAR")){
                return 2;
            }
            count ++;
        }
        
        
        
        int character = label.charAt(0);
        if (character <65 || character > 122 || (character >90 && character <97)){
            return 0;
        }
        int counter = 1;  // because we already checked character at 0
        while(counter < length){
            character = label.charAt(counter);
            
            if(character < 48 ||(character > 57 && character < 65) || (character >90 && character < 97) || character > 122 ){
                return 0;
            }
            counter ++;
        }    
        return 1;
    }
    
    /**
* The isMnemonic function will return a 1 or 0 depending on if the input paramater is a 
   * valid mnemonic.
* <p>
* Change Log:<br>
* 4/14/08 - Initial Code Entry Keith Hill <br>
* <p>
* Error Conditions Tested:<br>
* None <br>
* <p>
* Error Messages Generated: <br>
* None <br>
* <p>
* Date of module being installed: 4/18/08
     * <p>
<b>Original Author:</b> Keith Hill
<p>
     * 
* @param mnemonic  This string is being test to see if it is a valid mneominc
* @return 1 if it is a valid mnemonic and 0 if it is not
*/    
    public int isMnemonic (String mnemonic) {    
        String [] mnemonics = new String[5];
        mnemonics[0] = "CNTL";
        mnemonics[1] = "STACK";
        mnemonics[2] = "JUMP";
        mnemonics[3] = "SOPER";
        mnemonics[4] = "MOPER";
       
        int counter = 0;
        
        while(counter < 5){
            if(mnemonic.toUpperCase().equals(mnemonics[counter])){
                return 1;
            }
            counter ++;
        }
        
        return 0;
        
    }

    /**
    * The isPseuoOP function will return a 1 or 0 depending on if the input paramater is a 
    * valid Psuedo Operation.
    * <p>
    * Change Log:<br>
    * 4/14/08 - Initial Code Entry Keith Hill <br>
    * 4/21/08 - To Upper some things - Peter <br>
    * <p>
    * Error Conditions Tested:<br>
    * None <br>
    * <p>
    * Error Messages Generated: <br>
    * None <br>
    * <p>
    * Date of module being installed:  4/18/08
     * <p> 
<b>Original Author:</b> Keith Hill
<p>
    * @param pseudostring  This string is being test to see if it is a valid Psuedo Operation
    * @return 1 if it is a valid Psuedo Operation and 0 if it is not
    */      
    public int isPseudoOP (String pseudostring) {
        
        String[] pseudos = new String[11];
        pseudos[0] = "START";
        pseudos[1] = "END";
        pseudos[2] = "DAT";
        pseudos[3] = "EQU";
        pseudos[4] = "RESET";
        pseudos[5] = "SHVAR";
        pseudos[6] = "EXVAR";
        pseudos[7] = "DEBUG";
        pseudos[8] = "SKIPM";
        pseudos[9] = "ADC";
        pseudos[10] = "COMP";
        
        int length = 11;
       
        int counter = 0;
        while (counter < length){
            if(pseudos[counter].equals(pseudostring.toUpperCase())){
                return 1;
            }
            counter ++;
        }
        return 0;
    }
          
    /**
    * The purpose of is ParameterOverflow is to determine if the value of certain
    * items violate the requirements of the machine.  The valid type/value combinations are:<br>
    * n: 0-9<br>
    * nn: 0-99<br>
    * nnn: 0-999<br>
    * nmax: 0-1024<br>
    * nnnnn: -32768 - 32767<br>
    * Since the incomming value is a string, we first convert it to an integer value.  We then decide
    * which type we are working with with an if-else style of checking.  Once we determine the type we are
    * interested in, we check the applicable values and return the result of the test.
    * <p>
    * Change Log:<br>
    * 4/16/08 - Initial Code Entry Keith Hill <br>
    * 4/19/08 - Added the ability of star addressing check Keith Hill<br>
     *4/23/08 - Made return value more logical 1 if it was overflow<br>
    * <p>
    * Error Conditions Tested:<br>
    * None <br>
    * <p>
    * Error Messages Generated: <br>
    * None <br>
    * <p>
    * Date of module being installed: 4/18/08
     * <p>
<b>Original Author:</b> Keith Hill
<p>
    * @param stringparameter This is the integer value in the form of a string that must be tested
    * @param type  The type determines the valid values that are acceptable
    * @return 1 if overflow, and 0 if valid parameter
    */   
    public int isParameterOverflow (String stringparameter, String type) {
       
         int value = 0;
         if(stringparameter.contains("*+")){
            value = Integer.parseInt(stringparameter.substring(2, stringparameter.length()));
            value+=Control.location_counter;
        }
         else if(stringparameter.contains("*-")){
            value = Integer.parseInt(stringparameter.substring(2, stringparameter.length()));
            value-=Control.location_counter;
        } 
        else {
            try{
                value = new Integer(stringparameter);
            }catch(Exception e){
                return 1;
            }
        }
        
        if(type.equals("n")){
            if(value < 0 || value > 9){
                return 1;
            }
            return 0;
        }
        else if(type.equals("nn")){
            if(value < 0 || value > 99){
                return 1;
            }
            return 0;
        }
        else if (type.equals("nnn")){
            if(value < 0 || value > 999){
                return 1;
            }
            return 0;
        }
        else if(type.equals("nmax")){
            if(value < 0 || value > 1023){
                return 1;
            }
            return 0;
        }
        else if(type.equals("nnnnnn")){
            if(value < -32768 || value > 32767){
                return 1;
            }
            return 0;
        }
        else{
            return 1;
        }
    }

    /**
* The isLcInRanger function will return 0 or 1 depending on if the location counter 
* is in the range of the memory constraints.
* <p>
* Change Log:<br>
* 4/14/08 - Initial Code Entry Keith Hill <br>
* 4/21/08 - Fixed the upper limit check Keith Hill<br>
* <p>
* Error Conditions Tested:<br>
* None <br>
* <p>
* Error Messages Generated: <br>
* None <br>
* <p>
* Date of module being installed: 4/18/08
     * <p>
<b>Original Author:</b> Keith Hill
<p>
* @param locationcounter  This location counter will be checked to see if it is within the memory constraints of our machine.
* @return return 0 if the location counter is greater than 1023.  Otherwise, we return 1.
*/
    public int isLcInRange (int locationcounter) {
        if(locationcounter > 1023){
            return 0;
        }
        else {
            return 1;
        }
    }
    
    /**
    * The isEmptyString function will return a 1 or 0 depending on if the input paramater is an 
     * empty string.  We start out by first checking the length of the string.  If 
     * the length is 0, we know it is empty and return 1.  Otherwise, we proceed to check 
     * every character in the line and look for a non space character.  If we find one, 
     * we know it is not empty, so we return 0.  If it passes everything (ie: in cases that 
     * the line is all spaces), we return 1.
    * <p>
    * Change Log:<br>
    * 4/14/08 - Initial Code Entry Keith Hill <br>
    * <p>
    * Error Conditions Tested:<br>
    * None <br>
    * <p>
    * Error Messages Generated: <br>
    * None <br>
    * <p>
    * Date of module being installed: 4/18/08
     * <p>
<b>Original Author:</b>  Keith Hill
<p>
    * @param linestring  This string is being test to see if it is an empty string
    * @return 1 if it is an empty string and 0 if it is not.
    */
    public int isEmptyString (String linestring) {
        int length = linestring.length();
        if(length == 0 ){
            return 1;
        }
        int counter = 0;
        while (counter < length){
            if (linestring.charAt(counter) != ' '){    
                return 0;
            }
            counter ++;
        }
        return 1;
    }

    /**
     * This function checks if the given string is an integer.<p>
     * Change Log:<br>
     * 4/23/08 - Initial Code Entry - Yogesh Jindal <br>
     * <p>
     * Error Conditions Tested:<br>
     * None <br>
     * <p>
     * Error Messages Generated: <br>
     * None <br>
     * <p>
     * Date of module being installed: 4/23/08
     * @param string - any random string
     * @return Returns 1 if the input string was an integer else returns 0.   
     */
    public int isInt(String string){
        for(int index=0; index<string.length(); index++){
            if(!Character.isDigit(string.toCharArray()[index])){
                return 0;
            }
        }
        return 1;
    }
    
    /**
     * This function checks if the given string is a literal or not.<p>
     * Change Log:<br>
     * 4/23/08 - Initial Code Entry - Yogesh Jindal <br>
     * <p>
     * Error Conditions Tested:<br>
     * None.<br>
     * <p>
     * Error Messages Generated: <br>
     * None.<br>
     * <p>
     * Date of module being installed: 4/23/08
     * @param literal - Any string.
     * @return Returns 1 if the input string was a literal else returns 0.
     */
    public int isLiteral(String literal){
        if(literal.length()<3){
            return 0;
        }
        if(literal.contains(" ")){         
            while(literal.contains(" ")){
                literal = literal.replaceFirst(" ", "");
            }
        }        
        if(literal.substring(0,2).toUpperCase().compareTo("I=")==0){         
        }else if(literal.substring(0,2).toUpperCase().compareTo("C=")==0){         
        }else if(literal.substring(0,2).toUpperCase().compareTo("X=")==0){         
        }else if(literal.substring(0,2).toUpperCase().compareTo("B=")==0){         
        }else{
            return 0;
        }
        return 1;
    }
    
    /**
     * This function checks if the given string label is exvar or not.<p>
     * Change Log:<br>
     * 5/13/08 - Initial Code Entry - Yogesh Jindal <br>
     * <p>
     * Error Conditions Tested:<br>
     * None.<br>
     * <p>
     * Error Messages Generated: <br>
     * None.<br>
     * <p>
     * Date of module being installed: 5/13/08
     * @param label - Any string.
     * @return Returns 1 if the input string was an Exvar else returns 0.
     */
    public int isExternalLabel(String label){
        Table table_instance = new Table();
        String[] all_exvar = table_instance.getAllLabels("EXVAR");
        if(!all_exvar[0].contentEquals("0")){
            for(int index=1; index<all_exvar.length; index++){
                if(label.contentEquals(all_exvar[index])){
                    return 1;
                }
            }
        }
        return 0;
    }
}

